//
//  KKPhotosManager+Preview.m
//  KKPhotosKitDemo
//
//  Created by liaozhenming on 2017/9/1.
//  Copyright © 2017年 liaozhenming. All rights reserved.
//

#import "KKPhotosManager+Preview.h"
#import "KKPhotosManager+Private.h"

static NSString *_KKPhotosPreviewControllerStatus = @"_KKPhotosPreviewControllerStatus";

typedef NS_ENUM(NSUInteger, KKPhotosPreviewType) {
    KKPhotosPreviewTypeAlone = 0,       /**<一张图片*/
    KKPhotosPreviewTypeMore = 1,        /**<多张图片*/
    KKPhotosPreviewTypeAsset = 2,       /**<相册图片*/
};

@interface _KKImagePreviewItem : NSObject
@property (nonatomic, strong) UIImage *kk_thumbImage;
@property (nonatomic, strong) NSString *imagePath;
@property (nonatomic, assign) CGRect imageFrame;
+ (instancetype)itemWithThumbImage:(UIImage*)thumbImage imagePath:(NSString*)imagePath imageFrame:(CGRect)imageFrame;
@end

@implementation _KKImagePreviewItem
+ (instancetype)itemWithThumbImage:(UIImage*)thumbImage imagePath:(NSString*)imagePath imageFrame:(CGRect)imageFrame {
    _KKImagePreviewItem *item = [_KKImagePreviewItem new];
    item.kk_thumbImage = thumbImage;
    item.imagePath = imagePath;
    item.imageFrame = imageFrame;
    return item;
}
@end

#pragma mark - _KKImagePreview
@interface _KKImagePreview : UIView<UIScrollViewDelegate>
@property (nonatomic, strong) UIActivityIndicatorView *loadingActivity;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, assign) CGFloat initScale;    /**<初始的缩放倍数*/

@end

@implementation _KKImagePreview

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame: frame];
    if (self) {
        
        _scrollView = [[UIScrollView alloc] initWithFrame: self.bounds];
        _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _scrollView.delegate = self;
        _scrollView.minimumZoomScale = 1.0;
        _scrollView.backgroundColor = [UIColor blackColor];
        [self addSubview: _scrollView];
        
        _imageView = [[UIImageView alloc] init];
        _imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
        _imageView.userInteractionEnabled = YES;
        [_imageView addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(on_Tap:)]];
        [_scrollView addSubview: _imageView];
        
        _loadingActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
        _loadingActivity.center = CGPointMake(CGRectGetWidth(frame)/2.0, CGRectGetHeight(frame)/2.0);
        _loadingActivity.hidesWhenStopped = YES;
        [self addSubview: _loadingActivity];
    }
    return self;
}

#pragma mark - Public methods
- (void)public_setThumbImage:(UIImage*)thumbImage{
    _imageView.image = thumbImage;
    [_loadingActivity startAnimating];
    [self private_updateSubViewBounds];
}

- (void)public_setThumbImage:(UIImage*)thumbImage imageFrame:(CGRect)imageFrame {
    _imageView.frame = imageFrame;
    [_loadingActivity startAnimating];
    [self public_setThumbImage: thumbImage];
}

- (void)public_setImage:(UIImage*)image {
    _imageView.image = image;
    [self private_updateSubViewBounds];
    [_loadingActivity stopAnimating];
}

- (void)public_reset {
    if (_scrollView.zoomScale > _initScale) {
        [_scrollView setZoomScale: _initScale animated: YES];
    }
}

#pragma mark - Private methods
- (void)private_updateSubViewBounds {
    
    CGFloat scrollViewWidth = CGRectGetWidth(_scrollView.bounds);
    CGFloat scrollViewHeight = CGRectGetHeight(_scrollView.bounds);
    UIImage *image = _imageView.image;
    
    __weak typeof(self) weakSelf = self;
    if(image != nil){
        if (image.size.width > scrollViewWidth) {
            // 如果图片过大
            CGFloat scale = image.size.width / scrollViewWidth;
            CGFloat showImageHeight = image.size.height / scale;
            CGFloat origin_y = showImageHeight > scrollViewHeight ? 0.0 : fabs(scrollViewHeight - showImageHeight)/2.0;
            
            if (CGRectEqualToRect(self.imageView.frame, CGRectZero) ) {
                self.imageView.frame = CGRectMake(scrollViewWidth/2.0, scrollViewHeight/2.0, 1, 1);
            }
            
            [UIView animateWithDuration:0.15 animations:^{
                weakSelf.imageView.frame = CGRectMake(0, origin_y, scrollViewWidth, showImageHeight);
            }];
            
            [_scrollView setMaximumZoomScale: scale];
            [_scrollView setMinimumZoomScale: 1.0];
            [_scrollView setZoomScale: 1.0];
            _initScale = 1.0;
        }
        else {
            CGFloat origin_x = fabs(scrollViewWidth - image.size.width)/2.0;
            CGFloat scale = image.size.width / (scrollViewWidth - origin_x *2);
            CGFloat showImageHeight = image.size.height / scale;
            CGFloat origin_y = showImageHeight > scrollViewHeight ? 0.0 : fabs(scrollViewHeight - showImageHeight)/2.0;
            
            if (CGRectEqualToRect(self.imageView.frame, CGRectZero) ) {
                self.imageView.frame = CGRectMake(scrollViewWidth/2.0, scrollViewHeight/2.0, 1, 1);
            }
            
            [UIView animateWithDuration:0.15 animations:^{
                weakSelf.imageView.frame = CGRectMake(origin_x, origin_y, image.size.width, showImageHeight);
            }];
            
            
            [_scrollView setMinimumZoomScale:scale];
            [_scrollView setMaximumZoomScale: 2];
            [_scrollView setZoomScale:scale];
            _initScale = scale;
        }
    }
}

#pragma mark - Action methods

- (void)on_Tap:(UITapGestureRecognizer*)tapper {
    
    if (_scrollView.zoomScale > _initScale) {
        [_scrollView setZoomScale: _initScale animated: YES];
    }
    else {
        //  关闭图片显示
        [[NSNotificationCenter defaultCenter] postNotificationName: _KKPhotosPreviewControllerStatus object: nil];
    }
}

#pragma mark - UIScrollViewDelegate methods

- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _imageView;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    
    CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width) ? (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
    CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height) ? (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
    
    _imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY);
}

@end

#pragma mark - _KKPhotosPreviewCollectionViewCell Class
@interface _KKPhotosPreviewCollectionViewCell : UICollectionViewCell

@property (nonatomic, strong) _KKImagePreview *imagePreview;


@property (nonatomic, strong) PHAsset *assetItem;
@property (nonatomic, strong) _KKImagePreviewItem *previewItem;
@property (nonatomic, strong) NSString *imagePath;

@end

@implementation _KKPhotosPreviewCollectionViewCell

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame: frame];
    if (self) {
        self.clipsToBounds = false;
        self.backgroundColor = [UIColor blackColor];
        _imagePreview = [[_KKImagePreview alloc] initWithFrame: CGRectMake(5, 0, CGRectGetWidth(frame) - 10, CGRectGetHeight(frame))];
        [self addSubview: _imagePreview];
    }
    return self;
}


- (void)setAssetItem:(PHAsset *)assetItem {
    if (_assetItem != assetItem) {
        _assetItem = assetItem;
        
        __weak typeof(self) weakSelf = self;
        
        if (_assetItem.kk_thumbImage) {
            [_imagePreview public_setThumbImage: _assetItem.kk_thumbImage];
        }
        else {
            [KKPhotosManager kk_getThumbImageForAsset: _assetItem targetSize: CGSizeMake(100, 100) resultHandle:^(UIImage *image) {
                [weakSelf.imagePreview public_setThumbImage: image];
            }];
        }
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [KKPhotosManager kk_getThumbImageForAsset: _assetItem targetSize: self.frame.size resultHandle:^(UIImage *image) {
                [weakSelf.imagePreview public_setImage: image];
            }];
        });
    }
}

- (void)setPreviewItem:(_KKImagePreviewItem *)previewItem {
    if (_previewItem != previewItem) {
        _previewItem = previewItem;
        
        if (!CGRectEqualToRect(_previewItem.imageFrame, CGRectZero)) {
            [_imagePreview public_setThumbImage: _previewItem.kk_thumbImage imageFrame: _previewItem.imageFrame];
        }
        else {
            [_imagePreview public_setThumbImage: _previewItem.kk_thumbImage];
        }
        
        NSString *imagePath = [_previewItem imagePath];
        [self private_setImagePath: imagePath];
    }
}

- (void)setImagePath:(NSString *)imagePath {
    if (_imagePath != imagePath) {
        _imagePath = imagePath;
        
        [self.imagePreview public_setThumbImage: nil];
        [self private_setImagePath: imagePath];
    }
}

- (void)public_reset {
    [_imagePreview public_reset];
}

#pragma mark - Private methods
- (void)private_setImagePath:(NSString*)imagePath {
    if ([imagePath hasPrefix: @"http"]) {
        //  图片网址链接
    }
    else if([[NSFileManager defaultManager] fileExistsAtPath: imagePath]){
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            UIImage *image = [UIImage imageWithContentsOfFile: imagePath];
            [_imagePreview public_setImage: image];
        });
    }
    else {
    }
}

@end

#pragma mark - _KKPhotosPreviewController methods
@interface _KKPhotosPreviewController : UIViewController<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, assign) KKPhotosPreviewType previewType;

@property (nonatomic, strong) NSArray *arr_assetItems;  //  previewType =  KKPhotosPreviewTypeAsset

@property (nonatomic, strong) _KKImagePreviewItem *previewItem; // previewType = KKPhotosPreviewTypeAlone

@property (nonatomic, strong) NSArray *arr_imagePaths;      // previewType = KKPhotosPreviewTypeMore

@end

@implementation _KKPhotosPreviewController

- (void)loadView {
    [super loadView];
    
    UICollectionViewFlowLayout *flowLayout = [UICollectionViewFlowLayout new];
    flowLayout.itemSize = self.view.bounds.size;
    flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    flowLayout.minimumLineSpacing = CGFLOAT_MIN;
    flowLayout.minimumInteritemSpacing = CGFLOAT_MIN;
    self.collectionView = [[UICollectionView alloc] initWithFrame: self.view.bounds collectionViewLayout: flowLayout];
    self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
    self.collectionView.pagingEnabled = true;
    [self.collectionView registerClass: [_KKPhotosPreviewCollectionViewCell class] forCellWithReuseIdentifier: NSStringFromClass([_KKPhotosPreviewCollectionViewCell class])];
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;
    [self.view addSubview: self.collectionView];
    
    [self.collectionView addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(action_onTap:)]];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    if (self.previewType == KKPhotosPreviewTypeAsset) {
        NSInteger imageCount = [[_KKPhotosDataManger manager] arr_photoItems].count;
        NSString *title = [NSString stringWithFormat: @"发送(%@/%@)",@(imageCount),@([[_KKPhotosDataManger manager] itemMaxCount])];
        UIBarButtonItem *sendItem = [[UIBarButtonItem alloc] initWithTitle:title style: UIBarButtonItemStylePlain target: self action: @selector(action_send:)];
        
        self.navigationItem.rightBarButtonItem = sendItem;
    }
    else {
        UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style: UIBarButtonItemStylePlain target: self action: @selector(action_cancel:)];
        self.navigationItem.rightBarButtonItem = cancelItem;
    }
    
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(notification_listenStatus:) name:_KKPhotosPreviewControllerStatus object: nil];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver: self];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear: animated];
    [self.navigationController setNavigationBarHidden: YES];
    [self.navigationController setToolbarHidden: YES];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden: NO];
    [self.navigationController setToolbarHidden: NO];
}

#pragma mark - UICollectionView methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (self.previewType == KKPhotosPreviewTypeAsset) {
        return self.arr_assetItems.count;
    }
    else if (self.previewType == KKPhotosPreviewTypeMore) {
        return self.arr_imagePaths.count;
    }
    return 1;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    _KKPhotosPreviewCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: NSStringFromClass([_KKPhotosPreviewCollectionViewCell class]) forIndexPath: indexPath];
    
    if (self.previewType == KKPhotosPreviewTypeAsset) {
        cell.assetItem = self.arr_assetItems[indexPath.row];
    }
    else if(self.previewType == KKPhotosPreviewTypeAlone){
        cell.previewItem = self.previewItem;
    }
    else if (self.previewType == KKPhotosPreviewTypeMore) {
        cell.imagePath = self.arr_imagePaths[indexPath.row];
    }
    
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
    _KKPhotosPreviewCollectionViewCell *previewCell = (_KKPhotosPreviewCollectionViewCell*)cell;
    [previewCell public_reset];
}

#pragma mark - NSNotification methods
- (void)notification_listenStatus:(NSNotification*)notification {
    [self action_onTap: nil];
}

#pragma mark - Action methods
- (void)action_onTap:(UITapGestureRecognizer*)tapper {
    
    if (self.previewType == KKPhotosPreviewTypeAlone) {
        __weak typeof(self) weakSelf = self;
        [UIView animateWithDuration:0.25 animations:^{
            [weakSelf.navigationController.view setFrame: weakSelf.previewItem.imageFrame];
        }completion:^(BOOL finished) {
            [self.navigationController dismissViewControllerAnimated: false completion: nil];
        }];
        return;
    }
    
    if (self.navigationController.navigationBarHidden) {
        [self.navigationController setNavigationBarHidden: false animated: YES];
    }
    else {
        [self.navigationController setNavigationBarHidden: true animated: YES];
    }
}

- (void)action_send:(UIBarButtonItem*)item {
    
    [[NSNotificationCenter defaultCenter] postNotificationName: KKPhotosManager_Event_Save_Notification object: nil];
    
//    [KKPhotosManager kk_getImagesForAssets: [[_KKPhotosDataManger manager] arr_photoItems] original: false resultHandle:^(NSArray *images) {
//
//    }];
//
//    if ([[KKPhotosManager kk_defaultManager] resultBlock]) {
//        [KKPhotosManager kk_defaultManager].resultBlock(@[]);
//    }
    [self.navigationController dismissViewControllerAnimated: true completion: nil];
}

- (void)action_cancel:(UIBarButtonItem*)item {
    
    [[NSNotificationCenter defaultCenter]postNotificationName: KKPhotosManager_Event_Cancel_Notification object: nil];
    [self.navigationController dismissViewControllerAnimated: true completion: nil];
}

@end

#pragma mark - KKPhotosManager (Preview) methods
@implementation KKPhotosManager (Preview)

//  预览图片-参数为小图、大图链接或者路径、小图初始位置
+ (void)kk_previewImageWithThumbImage:(UIImage*)image orignImagePath:(NSString*)orignImagePath targetFrame:(CGRect)targetFrame {
    _KKPhotosPreviewController *previewController = [_KKPhotosPreviewController new];
    previewController.previewType = KKPhotosPreviewTypeAlone;
    previewController.previewItem = [_KKImagePreviewItem itemWithThumbImage: image imagePath: orignImagePath imageFrame: targetFrame];
    [self private_showPreviewController: previewController targetVC: nil animated: false];
}

//  预览一组图片-参数为图片链接或者路径
+ (void)kk_previewImagesWithImagePaths:(NSArray*)imagePaths {
    _KKPhotosPreviewController *previewController = [_KKPhotosPreviewController new];
    previewController.previewType = KKPhotosPreviewTypeMore;
    previewController.arr_imagePaths = imagePaths;
    [self private_showPreviewController: previewController targetVC: nil animated: false];
}

//  预览一组图片-参数为PHAsset数组
+ (void)kk_previewImagesWithPhotoAssets:(NSArray*)assetItems targetVC:(UIViewController*)targetVC {
    
    _KKPhotosPreviewController *previewController = [_KKPhotosPreviewController new];
    previewController.previewType = KKPhotosPreviewTypeAsset;
    previewController.arr_assetItems = assetItems;
    [self private_showPreviewController: previewController targetVC: targetVC animated: true];
}

#pragma mark - Private methods

+ (void)private_showPreviewController:(_KKPhotosPreviewController*)previewController targetVC:(UIViewController*)targetVC animated:(BOOL)animated{
    
    if (targetVC.navigationController) {
        [targetVC.navigationController pushViewController: previewController animated: animated];
    }
    else {
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: previewController];
        if (targetVC) {
            [targetVC presentViewController: navigationController animated: animated completion: nil];
        }
        else {
            [[[KKPhotosManager kk_defaultManager] kk_rootViewController] presentViewController: navigationController animated: animated completion: nil];
        }
    }
}

@end
